package com.wangsd.common.component;

import com.alibaba.fastjson.JSON;
import com.wangsd.common.exception.BusinessException;
import com.wangsd.web.sys.entity.SysCompany;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.URISyntaxException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;

class WxApiV3Service {

    private CloseableHttpClient httpClient = null;
    // 你的微信支付平台证书
    private static String certificate =  "-----BEGIN CERTIFICATE-----\n" +
            "MIID3DCCAsSgAwIBAgIUehZaF3rqM1wfyl7wwknSgCt4NkYwDQYJKoZIhvcNAQEL\n" +
            "BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT\n" +
            "FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg\n" +
            "Q0EwHhcNMjAwNDI5MTAxNzAwWhcNMjUwNDI4MTAxNzAwWjBuMRgwFgYDVQQDDA9U\n" +
            "ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl\n" +
            "bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGDAJDTjERMA8GA1UEBwwIU2hlblpo\n" +
            "ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBMCB1dM3Drp3S9Or3\n" +
            "b+0/vcekXgF5osOHio7O0H/Enhcizs/CKwfcFyL6lh1HKTJ2anZh7KkbpDvASFTT\n" +
            "CsudBn+ZZB3EnEwiPpTn3r575oEZjeXgpZtvSRYi8veQadyTVkyc5nSc44WPblF3\n" +
            "IOtcfJUBtFWdiEYYCDU1xO3H4Tm9nzqThp4ytR2T0LeGCq2fKzZzZyMwKNF/Fmu5\n" +
            "ihONAgy9bwFzJzcu00wPBY/jtLUZ1eIiDYpuYiFfUj4gtrTmrZ/MYUSCincumowo\n" +
            "Ix4ujvVaz6LOTGt6td58bew2r4Nn47wMn0jnAW82k9byX5C9NRYp3LIrc6/dVt33\n" +
            "VanDAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DBlBgNVHR8EXjBc\n" +
            "MFqgWKBWhlRodHRwOi8vZXZjYS5pdHJ1cy5jb20uY24vcHVibGljL2l0cnVzY3Js\n" +
            "P0NBPTFCRDQyMjBFNTBEQkMwNEIwNkFEMzk3NTQ5ODQ2QzAxQzNFOEVCRDIwDQYJ\n" +
            "KoZIhvcNAQELBQADggEBADwFwJSd5leShCAv9f+P1v8NCGuu8FdU7YeDJg0zOz1j\n" +
            "st1GV6Fkfg4G9Is9jieRECjsMEnVZYQ34F4cnZwbXdzlR9ZRrpYKxUkDUNSLT/QO\n" +
            "YwqwS5Jo84LkiDy8gl+HMabI96wMnGLSAB3f6YWDdWZXjK66NO1XacnXhSDE8n2F\n" +
            "r0Z0rR/NxRWqA+Io+dqlSho7gBhj7TpOTCHauY8HnIbMlol+K2Te3r97k9CWeo9c\n" +
            "Y3VtY1O3y441CB3WZTOg3ODCyigvcGgAEQCeRJXM4DFsqrpmJ6JMPUYaqFPMnQ1C\n" +
            "V+Gc0tqSPwYz//Pefx6Ht2xiq06/0O7v94ZMuHSyMYU=\n" +
            "-----END CERTIFICATE-----";

    protected WxApiV3Service(SysCompany company) {
        try {
            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                    new ByteArrayInputStream(company.getWxPrivateKey().getBytes("utf-8")));

            //使用自动更新的签名验证器，不需要传入证书
            AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                    new WechatPay2Credentials(company.getWxMchId(), new PrivateKeySigner(company.getWxMchSerialNo(), merchantPrivateKey)),
                    company.getWxApiV3Key().getBytes("utf-8"));

            //手动获取证书
//            X509Certificate wechatpayCertificate = PemUtil.loadCertificate(
//                    new ByteArrayInputStream(certificate.getBytes("utf-8")));
//            ArrayList<X509Certificate> listCertificates = new ArrayList<>();
//            listCertificates.add(wechatpayCertificate);

            httpClient = WechatPayHttpClientBuilder.create()
                    .withMerchant(company.getWxMchId(), company.getWxMchSerialNo(), merchantPrivateKey)
                    .withValidator(new WechatPay2Validator(verifier))
                    .build();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    protected String get(String url, Map<String, String> map) {
        String result = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            Set<Map.Entry<String, String>> entry = map.entrySet();
            for (Map.Entry<String, String> temp : entry) {
                uriBuilder.setParameter(temp.getKey(), temp.getValue());
            }
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            httpGet.addHeader("Accept", "application/json");

            CloseableHttpResponse response1 = httpClient.execute(httpGet);
            result = this.handleResponse(response1);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    protected String post(String url, Map<String, String> map) {
        String result = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            InputStream stream = new ByteArrayInputStream(JSON.toJSONString(map).getBytes("utf-8"));
            InputStreamEntity reqEntity = new InputStreamEntity(stream);
            reqEntity.setContentType("application/json");
            httpPost.setEntity(reqEntity);
            httpPost.addHeader("Accept", "application/json");

            CloseableHttpResponse response1 = httpClient.execute(httpPost);
            result = this.handleResponse(response1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    protected String handleResponse(CloseableHttpResponse response) {
        StringBuilder sb = new StringBuilder();
        BufferedReader br = null;
        try {
            if (response != null) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    br = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
                    String s = null;
                    while ((s = br.readLine()) != null) {
                        sb.append(s);
                    }
                }
                // 释放entity
                EntityUtils.consume(entity);
                if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    throw new BusinessException(JSON.parseObject(sb.toString()).getString("message"));
                }
            }
        }catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}
